www.gusucode.com > VC++ 树节点动态添加插入-源码程序 > VC++ 树节点动态添加插入-源码程序/code/NoteDlg.cpp

    //Download by http://www.NewXing.com
// NoteDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Note.h"
#include "NoteDlg.h"
#include "zip.h"
#include "unzip.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNoteDlg dialog

CNoteDlg::CNoteDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CNoteDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CNoteDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CNoteDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CNoteDlg)
	DDX_Control(pDX, IDC_TREE, m_wndTree);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CNoteDlg, CDialog)
	//{{AFX_MSG_MAP(CNoteDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ADDNEW, OnAddnew)
	ON_COMMAND(ID_OPEN, OnOpenFile)
	ON_COMMAND(ID_SAVEAS, OnSaveAs)
	ON_COMMAND(ID_ABOUT, OnAbout)
	ON_COMMAND(ID_NEW, OnNew)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
	ON_BN_CLICKED(IDOK, OnOk)
	ON_WM_CLOSE()
	ON_COMMAND(ID_EXIT, OnExit)
	ON_COMMAND(ID_SAVE, OnSave)
	ON_BN_CLICKED(IDC_DEL, OnDel)
	ON_BN_CLICKED(IDC_RENAME, OnRename)
	ON_WM_DESTROY()
	ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TREE, OnItemexpandedTree)
	ON_COMMAND(ID_FONT, OnFont)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNoteDlg message handlers

BOOL CNoteDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
    CRect treeRect;
	GetDlgItem(IDC_TREE)->GetWindowRect(&treeRect);
    ScreenToClient(&treeRect);
	CRect wndRect;
	GetClientRect(&wndRect);
	CRect editRect;
	editRect.left=treeRect.right+10;
	editRect.top=treeRect.top;
	editRect.right=wndRect.right-10;
	editRect.bottom=wndRect.bottom-10;
	DWORD style=0;
	//创建编辑控件,设置字体
	m_wndOwnEdit.Create(WS_CHILDWINDOW|WS_VISIBLE|WS_VSCROLL|WS_BORDER|ES_MULTILINE|ES_LEFT,editRect,this,IDC_EDIT);
  	m_wndOwnEdit.SetMargins(5,5); //设置显示边界
    m_pEditFont=new CFont();
	LOGFONT lf;
	GetFont()->GetLogFont(&lf);
	m_pEditFont->CreateFontIndirect(&lf);
	m_wndOwnEdit.SetFont(m_pEditFont);	
	//初始化变量
	m_dwDocCount=-1;
	m_dwItemCount=0;
	m_strCurOpenFile.Empty();
	m_bIsModified=FALSE;
	GetWindowText(m_strTitle); //获得程序刚启动时的窗口标题

	//创建树控件的图像列表
	m_pImgList=new CImageList();
	m_pImgList->Create(16,16,ILC_COLOR8,3,5);
	HICON hIcon;
	hIcon=AfxGetApp()->LoadIcon(IDI_CLASS_CLOSE);
	m_pImgList->Add(hIcon);
	hIcon=AfxGetApp()->LoadIcon(IDI_CLASS_OPEN);
	m_pImgList->Add(hIcon);
	hIcon=AfxGetApp()->LoadIcon(IDI_DOC);
	m_pImgList->Add(hIcon);
    m_wndTree.SetImageList(m_pImgList,TVSIL_NORMAL);

	m_wndTree.SetTextColor(RGB(0,0,255));
    
	//如果m_strShellFileName(由InitInstance()传递)非空,则说明程序时Shell打开的.
	if(!m_strShellFileName.IsEmpty())
	{
		if(!CheckFileFormat(m_strShellFileName))
			return FALSE;
		return OpenTree(m_strShellFileName);
	}
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CNoteDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CNoteDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CNoteDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//按钮"新增"的响应函数,向树控件中添加新项
void CNoteDlg::OnAddnew() 
{
	// TODO: Add your control notification handler code here

	CNewClassDlg dlg;

	HTREEITEM hParentItem=m_wndTree.GetSelectedItem();
	if(!hParentItem)
	{
		hParentItem=TVI_ROOT;
	    dlg.m_bIsRaDocEnabled=FALSE;
	}
	CString strName,strText;
	strName.Empty();
	strText.Empty();
	if(dlg.DoModal()==IDOK)
	{
		strName=dlg.m_strNewClassName;
		strText=dlg.m_strInfo;
	}
	if(!strName.IsEmpty())
	{
		HTREEITEM hItem=m_wndTree.InsertItem(strName,hParentItem);
		m_dwItemCount++;
		m_bIsModified=TRUE; //置文件更改标志
        if(dlg.m_bIsDoc) //添加的是否是文档项
		{
			m_dwDocCount++;
			m_wndTree.SetItemData(hItem,m_dwDocCount);
			m_wndTree.SetItemImage(hItem,2,2);
			if(!strText.IsEmpty())
			{
			    //把该文档项的内容写到一临时文件中
				
				CString strTmpFileName=CreateTempFileName();
				CFile file;
				file.Open(strTmpFileName,CFile::modeCreate|CFile::modeReadWrite);
				file.Write(strText,strText.GetLength());
				file.Close();
				DOC_INFO docInfo;
				docInfo.bIsNew=TRUE;
				docInfo.dwLength=strText.GetLength();
				docInfo.dwOffset=0;
				//把该文档项对应的文件名定向到该临时文件
				strcpy(docInfo.szFileName,strTmpFileName);
				m_arDoc.SetAtGrow(m_dwDocCount,docInfo);//向文档队列添加该文档信息
				
			}
			else
			{
				DOC_INFO docInfo;
				docInfo.bIsNew=TRUE;
				docInfo.dwLength=0;
				docInfo.dwOffset=0;
				strcpy(docInfo.szFileName," ");
				m_arDoc.SetAtGrow(m_dwDocCount,docInfo);
			}

		}
		else
			m_wndTree.SetItemData(hItem,-1);
		
		m_wndTree.Expand(hParentItem,TVE_EXPAND);
		m_wndTree.SelectItem(hItem);
		
		
	}
        
}
//保存树控件中的内容到文件
// 该函数具体功能见所附的<<说明.txt>>
BOOL CNoteDlg::SaveTree(CString strFileName)
{
  
   	
	HTREEITEM hWriteItem=m_wndTree.GetRootItem();
	if(!hWriteItem)
		return FALSE;
       CString strTmpDocFileName=CreateTempFileName();
	CString strTmpItemFileName=CreateTempFileName();

	CFile tmpDocFile;
	CFile tmpItemFile;

	tmpDocFile.Open(strTmpDocFileName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite);
	tmpItemFile.Open(strTmpItemFileName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyWrite);

	
	
	ITEM_INFO *pItemInfo;
	HGLOBAL hMemItemInfo=GlobalAlloc(GHND,sizeof(ITEM_INFO));
	pItemInfo=(ITEM_INFO*)GlobalLock(hMemItemInfo);
	GlobalUnlock(hMemItemInfo);
	
	DOC_INFO *pDocInfo;
	HGLOBAL hMemDocInfo=GlobalAlloc(GHND,sizeof(DOC_INFO));
	pDocInfo=(DOC_INFO*)GlobalLock(hMemDocInfo);
	GlobalUnlock(hMemDocInfo);
	
	DWORD dwItemData=-1;
	int flag=1;
	do{
		CString str=m_wndTree.GetItemText(hWriteItem);
		strcpy(pItemInfo->szName,(LPCTSTR)str);
		pItemInfo->nFlag=flag;
		pItemInfo->dwOffset=0;
		pItemInfo->dwLength=0;
		pItemInfo->bIsDoc=FALSE;
		dwItemData=m_wndTree.GetItemData(hWriteItem);
		if(dwItemData!=-1) //说明是文档项
		{
			pItemInfo->bIsDoc=TRUE;
			pDocInfo=&(m_arDoc.GetAt((int)dwItemData)); //获取该文档项的信息
			if(pDocInfo->dwLength>0)
			{
				if(pDocInfo->bIsNew==FALSE) //如不是新插入的项,则不需压缩数据
				{
					
					CFile dataFile;
					dataFile.Open(pDocInfo->szFileName,CFile::modeRead);
					pItemInfo->dwLength=pDocInfo->dwLength;
					pItemInfo->dwOffset=tmpDocFile.GetPosition();
					dataFile.Seek(pDocInfo->dwOffset,CFile::begin);
					LPVOID lpBuffer;
					HGLOBAL hMem=GlobalAlloc(GHND,pDocInfo->dwLength+1);
					lpBuffer=GlobalLock(hMem);
					dataFile.ReadHuge(lpBuffer,pDocInfo->dwLength); //直接从源文件(应该是m_strCurOpenFile)中读取压缩数据
					dataFile.Close();
					tmpDocFile.WriteHuge(lpBuffer,pDocInfo->dwLength);
					GlobalUnlock(hMem);
					GlobalFree(hMem);
				}
				else //是新插入的文档项,则要压缩数据
				{
						
					CString tpf; //压缩到临时文件tpf中
					tpf=CreateTempFileName();
					CZip zip(pDocInfo->szFileName);
					zip.SwapSize(tpf);
					CFile fl;
					fl.Open(tpf,CFile::modeRead|CFile::shareDenyWrite);
                    DWORD length=fl.GetLength();
				    pItemInfo->dwLength=length;
					pItemInfo->dwOffset=tmpDocFile.GetPosition();
					LPVOID lpBuffer;
					HGLOBAL hMem=GlobalAlloc(GHND,length);
					lpBuffer=GlobalLock(hMem);
					fl.Read(lpBuffer,length);
					fl.Close();
					tmpDocFile.WriteHuge(lpBuffer,length); //再从文件tpf中转移到tmpFile中
				
					DeleteFile(tpf); //删除临时文件
					GlobalUnlock(hMem);
					GlobalFree(hMem);
					
				}					
				tmpDocFile.Flush();
			
			}

		}
	
		tmpItemFile.Write(pItemInfo,sizeof(ITEM_INFO)); //向主文件写入项信息
		
	}while(hWriteItem=GetNextWriteItem(hWriteItem,flag));

	GlobalFree(hMemItemInfo);
	GlobalFree(hMemDocInfo);
   
	tmpItemFile.Flush();
	tmpItemFile.SeekToBegin();
    tmpItemFile.Close();

	tmpDocFile.Flush();
	tmpDocFile.SeekToBegin();
    
	//把项信息原文件压缩为名为strTpf的文件 
	CString strTpf;
	strTpf=CreateTempFileName();
	CZip zip(strTmpItemFileName);
	zip.SwapSize(strTpf);
	DeleteFile(strTmpItemFileName); //删除项信息原文件
	CFile tpf;
	tpf.Open(strTpf,CFile::modeRead|CFile::shareDenyWrite);
    //写入文件头
	CFile file;
	file.Open(strFileName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
	FILE_HEADER *pFHeader;
	HGLOBAL hMemFHeader=GlobalAlloc(GHND,sizeof(FILE_HEADER)+1);
	pFHeader=(FILE_HEADER*)GlobalLock(hMemFHeader);
	GlobalUnlock(hMemFHeader);
	pFHeader->dwItemCount=m_dwItemCount;
	pFHeader->dwDocOffset=sizeof(FILE_HEADER)+tpf.GetLength();
	pFHeader->dwItemInfoCompressedSize=tpf.GetLength();
	strcpy(pFHeader->szFlag,"鲍浩波"); //置文件标志
    file.Write(pFHeader,sizeof(FILE_HEADER)); //先写入文件头
	GlobalFree(hMemFHeader);
	//写入已压缩的项信息
	LPVOID lpBuffer;
	HGLOBAL hMemFile=GlobalAlloc(GHND,tpf.GetLength());
	lpBuffer=GlobalLock(hMemFile);
	GlobalUnlock(hMemFile);
	tpf.ReadHuge(lpBuffer,tpf.GetLength());
	file.WriteHuge(lpBuffer,tpf.GetLength());
	tpf.Close();
	DeleteFile(strTpf);  //删除信息临时压缩文件
    GlobalFree(hMemFile);
   
	//转移tmpDocFile中的内容到主文件中
	hMemFile=GlobalAlloc(GHND,tmpDocFile.GetLength());
	lpBuffer=GlobalLock(hMemFile);
	GlobalUnlock(hMemFile);
	tmpDocFile.ReadHuge(lpBuffer,tmpDocFile.GetLength());
	file.WriteHuge(lpBuffer,tmpDocFile.GetLength());
	GlobalFree(hMemFile);
	tmpDocFile.Close();
	file.Close();
	DeleteFile(strTmpDocFileName); //删除临时文件
	return TRUE;
}
//辅助函数,用于保存文件时获取下一个要保存的项,采用深度优先遍历

HTREEITEM CNoteDlg::GetNextWriteItem(HTREEITEM hItem, int &flag)
{

    if(m_wndTree.ItemHasChildren(hItem)) //有子节点
	{
		flag=-1;
		return m_wndTree.GetChildItem(hItem);
	}
	HTREEITEM hSibItem=m_wndTree.GetNextSiblingItem(hItem);
	if(hSibItem)// 无子节点,但有兄弟节点,则返回兄弟节点
	{
		flag=0;
		return hSibItem;
	}
	else //既无子节点,也无兄弟节点,则寻找上级节点的兄弟节点
	{    //flag表示上溯的级数
		flag=0;
		hSibItem=NULL;
		do{
			flag++;
			hItem=m_wndTree.GetParentItem(hItem);
			hSibItem=m_wndTree.GetNextSiblingItem(hItem);
		}while(hSibItem==NULL&&hItem);
		if(!hItem)
			return NULL;
		else
			return hSibItem;
	}

}



//菜单项"打开"的响应函数
void CNoteDlg::OnOpenFile() 
{
	// TODO: Add your command handler code here
    CFileDialog dlgFile(TRUE,"not",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"笔记本文件(*.not)|*.not|所有文件(*.*)|*.*|");
	if(dlgFile.DoModal()==IDOK)
	{
		CString strFileName=dlgFile.GetPathName();
	    if(!CheckFileFormat(strFileName))
			return;
		//格式正确,则提示保存以前更改
		if(m_bIsModified)
		{
			int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
			if(res==IDCANCEL)
				return;
			else if(res==IDYES)
				SaveModified();
			else
				m_bIsModified=FALSE;
		}
       	OpenTree(strFileName); //构造树
	
	}
}
//菜单项"保存为"的响应函数
void CNoteDlg::OnSaveAs() 
{
	// TODO: Add your command handler code here
	if(m_wndTree.GetCount()<=0)
		return;
	CFileDialog fileDlg(FALSE,"not",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"笔记本文件(*.not)|*.not|所有文件(*.*)|*.*|");
	if(fileDlg.DoModal()==IDOK)
	{
		SaveTree(fileDlg.GetPathName());
		OpenTree(fileDlg.GetPathName());
	    		
	}
	m_bIsModified=FALSE; 	
}
//菜单项"关于"的响应函数
void CNoteDlg::OnAbout() 
{
	// TODO: Add your command handler code here
    CAboutDlg dlg;
	dlg.DoModal();
}
//菜单项"新建"的响应函数,建立新文件
void CNoteDlg::OnNew() 
{
	// TODO: Add your command handler code here
	 if(m_bIsModified)
	{
		int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
		if(res==IDCANCEL)
			return;
		else if(res==IDYES)
			SaveModified();
		else if(res==IDNO)
			m_bIsModified=FALSE;
	}
	Reset();
	GetDlgItem(IDC_ADDNEW)->EnableWindow(TRUE);
	OnAddnew();
}
//构造树
//请先参阅所附的<<说明.txt>>
BOOL CNoteDlg::OpenTree(CString strFileName)
{
	   	//把原文件strFileName复制另一份用于填充树以及操作中的读写
	    Reset();
		CString strNewTitle;
		strNewTitle+=m_strTitle+" - "+strFileName;
		SetWindowText(strNewTitle);
		m_strOpenFileName=strFileName; //设置打开文件为strFileName
	   
		m_strCurOpenFile=CreateTempFileName();
		
		CopyFile(m_strOpenFileName,m_strCurOpenFile,FALSE);//复制文件
		
	   //先读出文件头中包含的dwItemCount和dwItemInfoCompressedSize;
	   	FILE_HEADER FHeader;
	    CFile file;
		file.Open(m_strCurOpenFile,CFile::modeRead);
		file.Read((LPVOID)(&FHeader),sizeof(FILE_HEADER));
		
		CString strTpfName=CreateTempFileName();
		CString strTempItemFileName=CreateTempFileName();
		//把文件中的ItemInfo压缩信息读到临时文件strTpfName
		CFile tpf;
		tpf.Open(strTpfName,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
		HGLOBAL hMem=GlobalAlloc(GHND,FHeader.dwItemInfoCompressedSize);
		LPVOID lpBuffer;
		lpBuffer=GlobalLock(hMem);
		GlobalUnlock(hMem);
		file.ReadHuge(lpBuffer,FHeader.dwItemInfoCompressedSize);
		tpf.WriteHuge(lpBuffer,FHeader.dwItemInfoCompressedSize);
		tpf.Flush();
		file.Close();
		tpf.Close();
		//解压缩所文件strTpfName到文件strTempItemFileName
		CUnZip unZip(strTpfName);
		unZip.SwapSize(strTempItemFileName);
		DeleteFile(strTpfName); //删除strTpfName
		CFile itemFile;
		itemFile.Open(strTempItemFileName,CFile::modeRead|CFile::shareDenyWrite);
	   
		DWORD dwItemCount=FHeader.dwItemCount;//总的节点项数
		//开始读各个Item信息
		ITEM_INFO *pItemInfo;
		UINT size=sizeof(ITEM_INFO);
		HGLOBAL hMemItemInfo=GlobalAlloc(GHND,size+1);
		pItemInfo=(ITEM_INFO*)GlobalLock(hMemItemInfo);
		GlobalUnlock(hMemItemInfo);
		itemFile.Read(pItemInfo,size);
			
		HTREEITEM hItem=TVI_ROOT;	
		hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
	    m_wndTree.SetItemData(hItem,m_dwDocCount);
		m_dwItemCount=1; //已插入了一个节点
		while((itemFile.Read(pItemInfo,size)==size)&&m_dwItemCount<dwItemCount)
		{
			m_dwItemCount++;
			if(pItemInfo->nFlag==-1) //表示要插入的节点时前一插入节点的子项
				hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
			else if(pItemInfo->nFlag==0)//表示要插入的节点时前一插入节点的兄弟项
			{   
				hItem=m_wndTree.GetParentItem(hItem);
				hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
			}
			else
			{
				for(int i=0;i<=pItemInfo->nFlag;i++)
					hItem=m_wndTree.GetParentItem(hItem);
				hItem=m_wndTree.InsertItem(pItemInfo->szName,hItem);
			}
			if(pItemInfo->bIsDoc) //如果该项是文档项,则把它的信息添加到队列m_arDoc中
			{
				m_dwDocCount++;   //文档项数加1
				m_wndTree.SetItemData(hItem,m_dwDocCount); //设置该项data为其在总的文档数中的序数
				m_wndTree.SetItemImage(hItem,2,2);
				DOC_INFO *pDocInfo;
				HGLOBAL hMemDocInfo=GlobalAlloc(GHND,sizeof(DOC_INFO)+1);
				pDocInfo=(DOC_INFO*)GlobalLock(hMemDocInfo);
				GlobalUnlock(hMemDocInfo);
				pDocInfo->bIsNew=FALSE;
				strcpy(pDocInfo->szFileName,m_strCurOpenFile);//把其对应的文件名设置为m_strCurOpenFile,
				pDocInfo->dwOffset=pItemInfo->dwOffset+FHeader.dwDocOffset;
				pDocInfo->dwLength=pItemInfo->dwLength;
			    pDocInfo->bIsNew=FALSE;
				m_arDoc.SetAtGrow(m_dwDocCount,*pDocInfo);
				GlobalFree(hMemDocInfo);

			}
			else //不是文档项,则设置ItemData为-1
			{
				m_wndTree.SetItemData(hItem,-1);
				m_wndTree.SetItemImage(hItem,0,0);
			}
		}
		itemFile.Close();
		DeleteFile(strTempItemFileName);
		GlobalFree(hMemItemInfo);
	   	m_wndTree.Expand(m_wndTree.GetRootItem(),TVE_TOGGLE);
	
		return TRUE;

}
//辅助函数,创建临时文件名
CString CNoteDlg::CreateTempFileName()
{
	char szPath[MAX_PATH];
	CString strTmpFileName;
	GetTempPath(MAX_PATH,szPath);
	GetTempFileName(szPath,"bhb",0,strTmpFileName.GetBuffer(MAX_PATH+1));
	strTmpFileName.ReleaseBuffer();
	return strTmpFileName;

}

//树中的被选项发生了变化
void CNoteDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	TVITEM tvItem;
	tvItem=pNMTreeView->itemNew;
    HTREEITEM hItem;
	hItem=tvItem.hItem; //获得被选项
	if(!hItem)
	{
		GetDlgItem(IDC_RENAME)->EnableWindow(FALSE);
		return;
	}
	GetDlgItem(IDC_RENAME)->EnableWindow();
	DWORD dwItemData=-1;
	dwItemData=m_wndTree.GetItemData(hItem); //获得该项的Data
	if(dwItemData!=-1) //如不是-1,则说明是文档节点
	{
		
		GetDlgItem(IDC_ADDNEW)->EnableWindow(FALSE); //文档节点下不可添加子节点
		GetDlgItem(IDC_DEL)->EnableWindow(TRUE);   //只有文档节点和无子节点的类节点可以被删除
		DOC_INFO docInfo;
		docInfo=m_arDoc.GetAt((int)dwItemData);  //从队列中获取该文档节点的信息
		if(docInfo.dwLength>0) //文档长度大于0
		{
			
			CFile dataFile;
			dataFile.Open(docInfo.szFileName,CFile::modeRead);
			LPVOID lpBuffer;
		   
			HGLOBAL hMem=GlobalAlloc(GHND,docInfo.dwLength);
			lpBuffer=GlobalLock(hMem);
			dataFile.Seek(docInfo.dwOffset,CFile::begin);
			dataFile.Read(lpBuffer,docInfo.dwLength); //读出文档内容
			GlobalUnlock(hMem);
			dataFile.Close();
			
		    //如果节点信息中的文件名不是m_strCupOpenFile,则说明不是压缩数据,可以直接填充编辑控件
			if(m_strCurOpenFile.CompareNoCase(docInfo.szFileName))
			{
				m_wndOwnEdit.SetWindowText((LPCTSTR)lpBuffer);
				GlobalFree(hMem);
			}
			else //是压缩数据,则把压缩数据写到临时文件tmpFile1中
			{
				CString tmpFile1;
				tmpFile1=CreateTempFileName();
				CFile fl;
				fl.Open(tmpFile1,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite);
				fl.Write(lpBuffer,docInfo.dwLength);
				fl.Flush();
				fl.Close();
				CString tmpFile2;
				tmpFile2=CreateTempFileName();
				CUnZip unZip(tmpFile1);
				unZip.SwapSize(tmpFile2); //把压缩数据解压到tmpFile2中
			   	DeleteFile(tmpFile1);
				fl.Open(tmpFile2,CFile::modeRead|CFile::shareDenyWrite);
				DWORD length;
				length=fl.GetLength();
				GlobalFree(hMem);
				hMem=GlobalAlloc(GHND,length);
				lpBuffer=GlobalLock(hMem);
				fl.ReadHuge(lpBuffer,length); //读出解压缩后的数据
			    GlobalUnlock(hMem);
				fl.Close();
				m_wndOwnEdit.SetWindowText((LPCTSTR)lpBuffer); //填充编辑控件
				GlobalFree(hMem);
				//重新设置该文档节点的信息
				docInfo.bIsNew=FALSE;
				docInfo.dwLength=length;
				docInfo.dwOffset=0;
				strcpy(docInfo.szFileName,tmpFile2); //重定向文档节点的对应文件名,下次显示该节点内容时就不必再解压缩
				m_arDoc.SetAt((int)dwItemData,docInfo);
			
			}
				
		}
	}
	else //如果不是文档节点,而是类节点
	{
		m_wndOwnEdit.SetWindowText("");
		GetDlgItem(IDC_ADDNEW)->EnableWindow(); //可以添加子节点
		if(m_wndTree.ItemHasChildren(hItem))
			GetDlgItem(IDC_DEL)->EnableWindow(FALSE);
		else
			GetDlgItem(IDC_DEL)->EnableWindow(TRUE);
	}


	*pResult = 0;
}




//重载IDCANCEL的响应函数,防止用户按下ESC后窗口关闭
void CNoteDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	return;
	CDialog::OnCancel();
	
}
//重载IDOK的响应函数,防止用户按下回车后窗口关闭
void CNoteDlg::OnOk() 
{
	// TODO: Add your control notification handler code here
	return;
}
//用户单击了窗口右上角的关闭按钮.
void CNoteDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
     if(m_bIsModified)
	 {
		int res=AfxMessageBox(IDS_SAVE_MODIFY,MB_YESNOCANCEL|MB_ICONQUESTION);
		if(res==IDCANCEL)
			return;
		else if(res==IDYES)
			SaveModified();
	 }
     //  删除临时文件
	CFileFind finder;
	if(!m_strCurOpenFile.IsEmpty())
	{
		if(finder.FindFile(m_strCurOpenFile))
			DeleteFile(m_strCurOpenFile);
		finder.Close();
		m_strCurOpenFile.Empty();
	}
	//删除各个文档节点对应的临时文件
	int upper;
    upper=m_arDoc.GetUpperBound();
	if(upper>-1)
	{
		DOC_INFO docInfo;
		
		for(int i=0;i<=upper;i++)
		{ 
			docInfo=m_arDoc.GetAt(i);
			if(finder.FindFile(docInfo.szFileName))
			{
				DeleteFile(docInfo.szFileName);
				finder.Close();
			}
		}
		m_arDoc.RemoveAll(); //清除队列
	}
	CDialog::OnClose();
	CDialog::OnOK();
		
}

//菜单项"退出"的响应函数
void CNoteDlg::OnExit() 
{
	// TODO: Add your command handler code here
	OnClose();
}
//该函数处理用那种方式保存
void CNoteDlg::SaveModified()
{
	if(m_wndTree.GetCount()>0)
	{
		if(m_strCurOpenFile.IsEmpty())
			OnSaveAs();
		else
			OnSave();
	}
}
//菜单项"保存"的响应函数
void CNoteDlg::OnSave() 
{
	// TODO: Add your command handler code here
	if(m_bIsModified==FALSE)
		return;
    //如果当前打开文件名为空,说明是建的文件,则调用OnSaveAs()函数
	if(m_strOpenFileName.IsEmpty()) 
	{
		OnSaveAs();
		return;
	}
	else
	{
		SaveTree(m_strOpenFileName); //保存完后重新打开新文件,在OpenTree中调用了Reset()函数
	    OpenTree(m_strOpenFileName);
	    m_bIsModified=FALSE;
	}
}
//按钮"删除"的响应函数,删除树中的节点
void CNoteDlg::OnDel() 
{
	// TODO: Add your control notification handler code here
	HTREEITEM hItem;
	hItem=m_wndTree.GetSelectedItem();
	HTREEITEM hParentItem;
	hParentItem=m_wndTree.GetParentItem(hItem);
	if(hItem)
	{
		m_wndTree.DeleteItem(hItem);
		m_dwItemCount--;
		if(m_wndTree.GetCount()<=0)
			if(m_strCurOpenFile.IsEmpty())
				{
					m_bIsModified=FALSE;
					return;
				}
        if(hParentItem)
			if(!m_wndTree.ItemHasChildren(hParentItem))
				m_wndTree.SetItemImage(hParentItem,0,0);
        m_bIsModified=TRUE;

	}
}
//按钮"更名"的响应函数
void CNoteDlg::OnRename() 
{
	// TODO: Add your control notification handler code here
	HTREEITEM hItem;
	hItem=m_wndTree.GetSelectedItem();
	if(hItem)
	{
		CString strOldName=m_wndTree.GetItemText(hItem);;
		CChangeNameDlg dlg;
		dlg.m_strNewName=dlg.m_strOldName=strOldName;

		if(dlg.DoModal()==IDOK)
		{
			if(dlg.m_strNewName.CompareNoCase(strOldName))
				m_wndTree.SetItemText(hItem,dlg.m_strNewName);
			m_bIsModified=TRUE;
		}
		

	}

}

void CNoteDlg::Reset()
{
    m_wndOwnEdit.SetWindowText("");
	SetWindowText(m_strTitle); //恢复窗口标题
	m_wndTree.DeleteAllItems(); //删除树中的所有项的
	m_dwDocCount=-1;
	m_dwItemCount=0;
	m_strOpenFileName.Empty();
  //  删除临时文件
	CFileFind finder;
	if(!m_strCurOpenFile.IsEmpty())
	{
		if(finder.FindFile(m_strCurOpenFile))
			DeleteFile(m_strCurOpenFile);
		finder.Close();
		m_strCurOpenFile.Empty();
	}
	//删除各个文档节点对应的临时文件
	int upper;
    upper=m_arDoc.GetUpperBound();
	if(upper>-1)
	{
		DOC_INFO docInfo;
		
		for(int i=0;i<=upper;i++)
		{ 
			docInfo=m_arDoc.GetAt(i);
			if(finder.FindFile(docInfo.szFileName))
			{
				DeleteFile(docInfo.szFileName);
				finder.Close();
			}
		}
		m_arDoc.RemoveAll(); //清除队列
	}

}


void CNoteDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
   m_wndOwnEdit.DestroyWindow(); //销毁创建的编辑控件
   delete m_pImgList;    //释放内存空间
   delete m_pEditFont;
}




void CNoteDlg::OnItemexpandedTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	TVITEM tvItem;
	tvItem=pNMTreeView->itemNew;
    HTREEITEM hItem;
	hItem=tvItem.hItem;
	if(!hItem)
		return;
	if(pNMTreeView->action==2)
		m_wndTree.SetItemImage(hItem,1,1);
	else if(pNMTreeView->action==1)
		m_wndTree.SetItemImage(hItem,0,0);	
	*pResult = 0;
}

//辅助函数,检查文件格式
BOOL CNoteDlg::CheckFileFormat(CString strFileName)
{

		CFile file;
		if(!file.Open(strFileName,CFile::modeRead))
		{
			AfxMessageBox(AFX_IDP_FAILED_TO_LAUNCH);
			return FALSE;
		}
		FILE_HEADER fileHeader;
        if(file.Read(&fileHeader,sizeof(FILE_HEADER))!=sizeof(FILE_HEADER))
		{
			AfxMessageBox(IDS_ERROR_FORMAT,MB_ICONEXCLAMATION|MB_OK);
			file.Close();
			return FALSE;
		}
		if(strcmp(fileHeader.szFlag,"鲍浩波")!=0) 
		{
			AfxMessageBox(IDS_ERROR_FORMAT,MB_ICONEXCLAMATION|MB_OK);
			file.Close();
			return FALSE;
		}
		file.Close();
		return TRUE;
}
//设置文档内容显示框的字体.
void CNoteDlg::OnFont() 
{
	// TODO: Add your command handler code here
	LOGFONT lf;
	m_wndOwnEdit.GetFont()->GetLogFont(&lf);
	CFontDialog  fontDlg(&lf, CF_SCREENFONTS);
	if(fontDlg.DoModal()==IDOK)
	{
		fontDlg.GetCurrentFont(&lf);
		m_pEditFont->Detach();
		m_pEditFont->CreateFontIndirect(&lf);
		m_wndOwnEdit.SetFont(m_pEditFont);
	}

	
}